package controller

import (
	"fmt"
	"gg_server/db"
	"gg_server/model"
	"gg_server/response"
	"gg_server/util"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

// 登录或注册接口

type loginRegister struct{}

var LoginRegisterController *loginRegister

func init() {
	LoginRegisterController = &loginRegister{}
}

// 注册
func (lr *loginRegister) Register(ctx *gin.Context) {
	var user model.User

	// 接收用户传递的注册数据
	/* 	if err := ctx.ShouldBind(&user); err != nil {
		response.GetError().ParameterError("参数不完整")
	} */

	// 获取post form参数
	user.Name = ctx.PostForm("name")
	user.Account, _ = strconv.Atoi(ctx.PostForm("account"))
	user.Password = ctx.PostForm("password")
	sex, _ := strconv.Atoi(ctx.PostForm("sex"))
	user.Sex = int8(sex)
	user.Individuality = ctx.PostForm("individuality")

	// 判断密码长度和用户昵称长度
	if len(user.Name) < 3 || len(user.Password) < 8 {
		// 返回错误 用户昵称或密码长度不够
		response.GetError().ParameterError("用户昵称应为3个字符以上,用户密码应为8个字符以上")
		return
	}

	// 校验用户性别是否合法
	if !(user.Sex == 1 || user.Sex == 2) {
		// 返回错误 用户性别不合法
		response.GetError().ParameterError("性别不合法")
		return
	}

	// 校验用户账号长度 是否大于6小于10
	if len(fmt.Sprint(user.Account)) > 10 || len(fmt.Sprint(user.Account)) < 6 {
		// 返回错误
		response.GetError().ParameterError("账号长度必须大于6小于10")
		return
	}

	// 如果没有问题则开始储存头像
	// 储存头像
	/*
		这一步并没有开始储存，防止 向数据库 插入用户时
		存在同一个用户，使用先获取到地址等向数据库插入用户成功后
		才储存头像
	*/
	avatar, err := ctx.FormFile("avatar")
	if err != nil {
		// 返回错误
		response.GetError().ParameterError("没有上传头像")
		return
	}
	dst, src := util.Upload.GetUploadDst("avatar", avatar, &util.CheckImg)
	user.Avatar = src

	// 加密密码
	user.Password = util.GetMd5String(user.Password)
	// 添加创建时间
	user.CreateTime = time.Now()

	// 向数据库插入
	result := db.CreateSQLDB().Create(&user)

	if result.Error != nil {
		response.GetError().ParameterError("存在相同的账号，请更换账号")
		return
	}

	// 如果都没有问题才 储存上传的头像
	ctx.SaveUploadedFile(avatar, dst)

	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Msg:  "注册成功",
		Data: gin.H{},
	})
}

type LoginUser struct {
	Account  int    `json:"account" form:"account" binding:"required"`
	Password string `json:"password" form:"password" binding:"required"`
}

// 登陆
func (lr *loginRegister) Login(ctx *gin.Context) {
	// 接收客户端请求的json数据
	var loginUser LoginUser
	if ctx.ShouldBind(&loginUser) != nil {
		response.GetError().ParameterError("参数不完整")
		return
	}

	user := model.User{}
	// 向数据库查找用户
	result := db.CreateSQLDB().Where("account = ?", loginUser.Account).First(&user)
	// 判断通过账号是否查找到用户
	if result.Error != nil {
		response.GetError().UnauthorizedError("没有找到该账号")
		return
	}

	// 判断密码是否正确
	if user.Password != util.GetMd5String(loginUser.Password) {
		response.GetError().UnauthorizedError("密码错误，请重新输入")
		return
	}

	// 账号密码正确，签发token
	issuedJwt := util.MyJwt{
		Id:   user.Id,
		Name: user.Name,
	}
	// 获取token
	token := issuedJwt.CreateJwt()

	// 将token 返回给客户端
	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Code: 200,
		Msg:  "登陆成功",
		Data: gin.H{
			"token": token,
		},
	})
}

// 校验token
func (lr *loginRegister) Verify(ctx *gin.Context) {
	tokenString := ctx.GetHeader("Authorization")[7:]

	// 验证token
	jwtInfo := util.MyJwt{}
	b := jwtInfo.VerifyJwt(tokenString)
	if !b {
		response.GetError().ForbiddenError("token验证失败")
	}

	user := model.User{
		Id: jwtInfo.Id,
	}
	// 查询token下的用户信息
	db.CreateSQLDB().Find(&user)

	response.SendSuccessMsg(ctx, &response.SuccessMsg{
		Code: 200,
		Msg:  "token验证成功",
		Data: gin.H{
			"id":   jwtInfo.Id,
			"name": jwtInfo.Name,
			"user": user,
		},
	})
}
